Header file arithmetic_policy.hpp

namespace type_safe
{
    class default_arithmetic;
    
    class undefined_behavior_arithmetic;
    
    class checked_arithmetic;
    
    using arithmetic_policy_default = 'hidden';
}

Class type_safe::default_arithmetic [types]

class default_arithmetic
{
public:
    template <typename T>
    static constexpr T do_addition(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_subtraction(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_multiplication(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_division(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_modulo(const T& a, const T& b) noexcept;
};

An ArithmeticPolicy that behaves like the default integer implementations: Signed under/overflow is UB, unsigned under/overflow wraps around.

Class type_safe::undefined_behavior_arithmetic [types]

class undefined_behavior_arithmetic
{
public:
    template <typename T>
    static constexpr T do_addition(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_subtraction(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_multiplication(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_division(const T& a, const T& b) noexcept;
    
    template <typename T>
    static constexpr T do_modulo(const T& a, const T& b) noexcept;
};

An ArithmeticPolicy where under/overflow is always undefined behavior, albeit checked when assertions are enabled.

Class type_safe::checked_arithmetic [types]

class checked_arithmetic
{
public:
    class error
    : public std::range_error
    {
    public:
        error(const char* msg);
    };
    
    template <typename T>
    static constexpr T do_addition(const T& a, const T& b);
    
    template <typename T>
    static constexpr T do_subtraction(const T& a, const T& b);
    
    template <typename T>
    static constexpr T do_multiplication(const T& a, const T& b);
    
    template <typename T>
    static constexpr T do_division(const T& a, const T& b);
    
    template <typename T>
    static constexpr T do_modulo(const T& a, const T& b);
};

An ArithmeticPolicy where under/overflow throws an exception.

Notes: If exceptions are not supported, this is will assert.

Type alias type_safe::arithmetic_policy_default [types]

using arithmetic_policy_default = 'hidden';

The default ArithmeticPolicy.

It depends on the TYPE_SAFE_ARITHMETIC_UB macro, and is either ts::undefined_behavior_arithmetic or ts::default_arithmetic.